home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * Copyright (C) 1987 Pehong Chen (phc@renoir.berkeley.edu)
- * Computer Science Division
- * University of California, Berkeley
- *
- */
-
- #include "mkind.h"
- #include "genind.h"
-
- static FIELD_PTR curr = NULL;
- static FIELD_PTR prev = NULL;
- static FIELD_PTR begin = NULL;
- static FIELD_PTR end = NULL;
- static FIELD_PTR range_ptr;
- static int level = 0;
- static int prev_level = 0;
- static char *encap = NULL;
- static char *prev_encap = NULL;
- static int in_range = FALSE;
- static int encap_range = FALSE;
- static int range_lc;
- static char buff[2*LINE_MAX];
- static char line[2*LINE_MAX]; /* output buffer */
- static int ind_lc = 0; /* overall line count */
- static int ind_ec = 0; /* erroneous line count */
- static int ind_indent;
-
-
- void
- gen_ind()
- {
- int n;
- int tmp_lc;
-
- MESSAGE("Generating output file %s...", ind_fn);
- PUT(preamble);
- ind_lc += prelen;
- if (init_page)
- insert_page();
-
- /* reset counters for putting out dots */
- idx_dc = 0;
- for (n = 0; n < idx_gt; n++) {
- if (idx_key[n]->type != DUPLICATE)
- if (make_entry(n)) {
- IDX_DOT(DOT_MAX);
- }
- }
-
- tmp_lc = ind_lc;
- if (in_range) {
- curr = range_ptr;
- IND_ERROR("Unmatched range opening operator %c.\n", idx_ropen);
- }
-
- prev = curr;
- flush_line(TRUE);
- PUT(postamble);
- tmp_lc = ind_lc + postlen;
- if (ind_ec == 1) {
- DONE(tmp_lc, "lines written", ind_ec, "warning");
- } else {
- DONE(tmp_lc, "lines written", ind_ec, "warnings");
- }
- }
-
-
- static int
- make_entry(n)
- int n;
- {
- int let;
-
- /* determine current and previous pointer */
- prev = curr;
- curr = idx_key[n];
-
- /* check if current entry is in range */
- if ((*curr->encap == idx_ropen) || (*curr->encap == idx_rclose))
- encap = &(curr->encap[1]);
- else
- encap = curr->encap;
-
- /* determine the current nesting level */
- if (n == 0) {
- prev_level = level = 0;
- make_item();
- let = *curr->sf[0];
- LETTERHEAD;
- } else {
- prev_level = level;
- for (level = 0; level < FIELD_MAX; level++)
- if (STRNEQ(curr->sf[level], prev->sf[level]) ||
- STRNEQ(curr->af[level], prev->af[level]))
- break;
- if (level < FIELD_MAX)
- new_entry();
- else
- old_entry();
- }
-
- if (*curr->encap == idx_ropen)
- if (in_range) {
- IND_ERROR("Extra range opening operator %c.\n", idx_ropen);
- } else {
- in_range = TRUE;
- range_ptr = curr;
- range_lc = ind_lc;
- }
- else if (*curr->encap == idx_rclose)
- if (in_range) {
- in_range = FALSE;
- if (STRNEQ(&(curr->encap[1]), "") &&
- STRNEQ(prev_encap, &(curr->encap[1]))) {
- IND_ERROR("Range closing operator has an inconsitent encapsulator %s.\n", &(curr->encap[1]));
- }
- } else {
- IND_ERROR("Unmatched range closing operator %c.\n", idx_rclose);
- }
- else if ((*curr->encap != NULL) &&
- STRNEQ(curr->encap, prev_encap) && in_range)
- IND_ERROR("Inconsistent page encapsulator %s within range.\n", curr->encap);
- return (1);
- }
-
-
- static void
- make_item()
- {
- int i;
-
- if (level > prev_level) {
- /* ascending level */
- if (*curr->af[level] == NULL)
- sprintf(line, "%s%s", item_u[level], curr->sf[level]);
- else
- sprintf(line, "%s%s", item_u[level], curr->af[level]);
- ind_lc += ilen_u[level];
- } else {
- /* same or descending level */
- if (*curr->af[level] == NULL)
- sprintf(line, "%s%s", item_r[level], curr->sf[level]);
- else
- sprintf(line, "%s%s", item_r[level], curr->af[level]);
- ind_lc += ilen_r[level];
- }
-
- i = level + 1;
- while (i < FIELD_MAX && *curr->sf[i] != NULL) {
- PUT(line);
- if (*curr->af[i] == NULL)
- sprintf(line, "%s%s", item_x[i], curr->sf[i]);
- else
- sprintf(line, "%s%s", item_x[i], curr->af[i]);
- ind_lc += ilen_x[i];
- i++;
- }
-
- ind_indent = 0;
- strcat(line, delim_p[level]);
- SAVE;
- }
-
-
- static void
- new_entry()
- {
- char let;
- FIELD_PTR ptr;
-
- if (in_range) {
- ptr = curr;
- curr = range_ptr;
- IND_ERROR("Unmatched range opening operator %c.\n", idx_ropen);
- in_range = FALSE;
- curr = ptr;
- }
-
- flush_line(TRUE);
-
- /* beginning of a new group? */
- if (((curr->group != ALPHA) && (curr->group != prev->group)) ||
- ((curr->group == ALPHA) &&
- ((let = TOLOWER(curr->sf[0][0])) != (TOLOWER(prev->sf[0][0]))))) {
- PUT(group_skip);
- ind_lc += skiplen;
- /* beginning of a new letter? */
- LETTERHEAD;
- }
- make_item();
- }
-
-
- static void
- old_entry()
- {
- int diff;
-
- /* current entry identical to previous one: append pages */
- diff = page_diff(end, curr);
- if ((prev->type == curr->type) && (diff != -1) &&
- (((diff == 0) && (prev_encap != NULL) && STREQ(encap, prev_encap)) ||
- (merge_page && (diff == 1) &&
- (prev_encap != NULL) && STREQ(encap, prev_encap)) ||
- in_range)) {
- end = curr;
- /* extract in-range encaps out */
- if (in_range &&
- (*curr->encap != NULL) &&
- (*curr->encap != idx_rclose) &&
- STRNEQ(curr->encap, prev_encap)) {
- sprintf(buff, "%s%s%s%s%s", encap_p, curr->encap,
- encap_i, curr->lpg, encap_s);
- wrap_line(FALSE);
- }
- if (in_range)
- encap_range = TRUE;
- } else {
- flush_line(FALSE);
- if ((diff == 0) && (prev->type == curr->type)) {
- IND_ERROR("Conflicting entries: multiple encaps for the same page under same key.\n", "");
- } else if (in_range && (prev->type != curr->type)) {
- IND_ERROR("Illegal range formation: starting & ending pages are of different types.\n", "");
- } else if (in_range && (diff == -1)) {
- IND_ERROR("Illegal range formation: starting & ending pages cross chap/sec breaks.\n", "");
- }
- SAVE;
- }
- }
-
-
- static int
- page_diff(a, b)
- FIELD_PTR a;
- FIELD_PTR b;
- {
- short i;
-
- if (a->count != b->count)
- return (-1);
- for (i = 0; i < a->count-1; i++)
- if (a->npg[i] != b->npg[i])
- return (-1);
- return (b->npg[b->count-1] - a->npg[a->count-1]);
- }
-
-
- static void
- flush_line(print)
- int print;
- {
- char tmp[LINE_MAX];
-
- if (page_diff(begin, end) != 0)
- if (encap_range || (page_diff(begin, prev) > 1)) {
- sprintf(buff, "%s%s%s", begin->lpg, delim_r, end->lpg);
- encap_range = FALSE;
- } else
- sprintf(buff, "%s%s%s", begin->lpg, delim_n, end->lpg);
- else
- strcpy(buff, begin->lpg);
-
- if (*prev_encap != NULL) {
- strcpy(tmp, buff);
- sprintf(buff, "%s%s%s%s%s", encap_p, prev_encap, encap_i, tmp, encap_s);
- }
-
- wrap_line(print);
- }
-
-
- static void
- wrap_line(print)
- int print;
- {
- int len;
-
- len = strlen(line) + strlen(buff) + ind_indent;
- if (print) {
- if (len > linemax) {
- PUTLN(line);
- PUT(indent_space);
- ind_indent = indent_length;
- } else
- PUT(line);
- PUT(buff);
- } else {
- if (len > linemax) {
- PUTLN(line);
- sprintf(line, "%s%s%s", indent_space, buff, delim_n);
- ind_indent = indent_length;
- } else {
- strcat(buff, delim_n);
- strcat(line, buff);
- }
- }
- }
-
-
- static void
- insert_page()
- {
- int i = 0;
- int j = 0;
- int page = 0;
-
- if (even_odd >= 0) {
- /* find the rightmost digit */
- while (pageno[i++] != NULL);
- j = --i;
- /* find the leftmost digit */
- while (isdigit(pageno[--i]) && i > 0);
- if (! isdigit(pageno[i]))
- i++;
- /* convert page from literal to numeric */
- page = strtoint(&pageno[i]) + 1;
- /* check even-odd numbering */
- if (((even_odd == 1) && (page%2 == 0)) || ((even_odd == 2) && (page%2 == 1)))
- page++;
- pageno[j+1] = NULL;
- /* convert page back to literal */
- while (page >= 10) {
- pageno[j--] = TOASCII(page%10);
- page = page / 10;
- }
- pageno[j] = TOASCII(page);
- if (i < j) {
- while (pageno[j] != NULL)
- pageno[i++] = pageno[j++];
- pageno[i] = NULL;
- }
- }
-
- PUT(setpage_open);
- PUT(pageno);
- PUT(setpage_close);
- ind_lc += setpagelen;
- }
-
-